package com.shawn.dubbo.api;

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.shawn.commons.utils.CommentType;
import com.shawn.dubbo.utils.IdWorker;
import com.shawn.model.mongo.Comment;
import com.shawn.model.mongo.FocusUser;
import com.shawn.model.mongo.Video;
import com.shawn.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Date;
import java.util.List;

@DubboService
public class VideoApiImpl implements VideoApi{
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdWorker idWorker;

    @Override
    public String save(Video vi) {
        vi.setCreated(System.currentTimeMillis());
        vi.setVid(idWorker.getNextId("video"));
        Video video = mongoTemplate.save(vi);
        return video.getId().toHexString();
    }

    /**
     * 分页获取推荐视频不包含该用户
     *
     * @param page     页面
     * @param pageSize 页面大小
     * @param userId   用户id
     * @return {@link List}<{@link Video}>
     */
    @Override
    public PageResult<Video> getVideos(Integer page, Integer pageSize, Long userId) {
        Query query = new Query().addCriteria(Criteria.where("userId").ne(userId));
        long count = mongoTemplate.count(query, Video.class);
        query.with(Sort.by(Sort.Order.desc("created")))
                .skip((long) (page - 1) *pageSize)
                .limit(pageSize);
        List<Video> videos = mongoTemplate.find(query, Video.class);
        return new PageResult<>(page,pageSize,(int)count,videos);
    }

    /**根据推荐vid集合查询视频
     * @param vidList 请看列表
     * @param userId  用户id
     * @return {@link List}<{@link Video}>
     */
    @Override
    public List<Video> getByIdList(List<Long> vidList, Long userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("vid").in(vidList))
                .addCriteria(Criteria.where("userId").ne(userId));
        return mongoTemplate.find(query,Video.class);
    }

    /**
     * 是否喜欢视频
     *
     * @param videoId 视频id
     * @param type    类型
     * @return {@link Integer}
     */
    @Override
    public Integer whetherLikeVideo(String videoId,Long userId ,Integer type) {
        //更新视频表点赞数
        Query query = new Query().addCriteria(Criteria.where("id").in(new ObjectId(videoId)));

        Update update = new Update();
        update.inc("likeCount",type);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.upsert(true);

        Video video = mongoTemplate.findAndModify(query, update, options, Video.class);
        if (video==null){
            return 0;
        }
        //将数据保存到评论表里
        if (type.equals(1)) {
            //生成评论
            Comment comment = new Comment();
            comment.setPublishId(new ObjectId(videoId));
            comment.setCommentType(type);
            comment.setUserId(userId);
            comment.setPublishUserId(video.getUserId());
            comment.setCreated(System.currentTimeMillis());
            mongoTemplate.save(comment);
            //将评论数据保存进redis
        }else {
            //删除点赞 喜欢评论
            Query comQuery = new Query();
            comQuery.addCriteria(Criteria.where("publishId").is(new ObjectId(videoId)))
                    .addCriteria(Criteria.where("userId").is(userId))
                    .addCriteria(Criteria.where("commentType").is(CommentType.LIKE.getType()));
            //删除评论表
            mongoTemplate.remove(comQuery, Comment.class);
        }

        return video.getLikeCount();
    }

    /**
     * 发表评论
     *
     * @param userId  用户id
     * @param id      id
     * @param comment 评论
     * @return {@link Integer}
     */
    @Override
    public Integer publishComment(Long userId, String id, String comment) {
        //更新视频评论数
        Query query = new Query().addCriteria(Criteria.where("id").in(new ObjectId(id)));

        Update update = new Update();
        update.inc("likeCount",CommentType.COMMENT.getType());
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.upsert(true);
        Video video = mongoTemplate.findAndModify(query, update, options, Video.class);

        if (video==null){
            return 0;
        }
        Comment co = new Comment();
        co.setPublishId(new ObjectId(id));
        co.setCommentType(CommentType.COMMENT.getType());
        co.setContent(comment);
        co.setUserId(userId);
        co.setPublishUserId(video.getUserId());
        co.setCreated(System.currentTimeMillis());
        mongoTemplate.save(co);
        return video.getCommentCount();
    }

    /**
     * 是否关注作者
     *
     * @param userId   用户id
     * @param authorId 作者id
     * @param type     类型
     */
    @Override
    public void whetherFocusAuthor(Long userId, Long authorId, Integer type) {
        //查找关注表,查看是否已有数据
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId)).addCriteria(Criteria.where("focusUserId").is(authorId));
        boolean exists = mongoTemplate.exists(query, FocusUser.class);
        //关注或取消关注作者更新关注表
        if (exists){
            Update update = new Update();
            update.set("hasFocus",type);
            update.set("updated",System.currentTimeMillis());
            mongoTemplate.updateFirst(query, update, FocusUser.class);
        }else {
            FocusUser fu = new FocusUser();
            fu.setUserId(userId);
            fu.setFocusUserId(authorId);
            fu.setHasFocus(type);
            fu.setCreated(System.currentTimeMillis());
            fu.setUpdated(System.currentTimeMillis());
            mongoTemplate.save(fu);
        }
    }

    /**
     * 根据用户id得到视频页面
     *
     * @param page     页面
     * @param pageSize 页面大小
     * @param userId   用户id
     * @return {@link PageResult}<{@link Video}>
     */
    @Override
    public PageResult<Video> getVideoByPage(Integer page, Integer pageSize, Long userId,String sortProp,String sortOrder) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        long count = mongoTemplate.count(query, Video.class);
        if ("descending".equals(sortOrder)){
            query.with(Sort.by(Sort.Order.desc("created")));
        }else {
            query.with(Sort.by(Sort.Order.asc("created")));
        }
        query.skip((long) (page - 1) *pageSize)
                .limit(pageSize);
        List<Video> videos = mongoTemplate.find(query, Video.class);
        return new PageResult<>(page,pageSize,(int)count,videos);
    }
}
